﻿/**
 * Copyright (C) 2012 original author and authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NGuice.Inject.Spi;
using NGuice.Inject.Internal.Util;

namespace NGuice.Inject.Internal
{
    //complete!
    /// <summary>
    /// 在一个注入器中可扩展的数据。此类用于允许本地或者父注入器数据作为一个单元被访问
    /// </summary>
    internal interface IState
    {
        IState Parent
        {
            get;
        }

        /// <summary>
        /// 获取在一个模块中显式指定的binding
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        BindingImpl<T> GetExplicitBinding<T>(Key<T> key);

        /// <summary>
        /// 非泛型方法！
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <seealso cref="GetExplicitBinding"/>
        IBindingImpl GetExplicitBinding(Key key);

        /// <summary>
        /// 仅仅在此层次返回显式的binding
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IDictionary<Key<T>, IBinding<T>> GetExplicitBindingsThisLevel<T>();

        /// <summary>
        /// 仅仅在此层次返回显式的binding
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IDictionary<Key, IBinding> GetExplicitBindingsThisLevel();

        void PutBinding<T>(Key<T> key, BindingImpl<T> binding);

        void PutBinding(Key key, IBindingImpl binding);

        /// <summary>
        /// 获取匹配的scope
        /// </summary>
        /// <param name="scopingAnnotation"></param>
        /// <returns></returns>
        IScope GetScope(Type scopingAnnotation);

        IScope GetScope<T>() where T : Attribute;

        void PutAnnotation(Type annotationType, IScope scope);
        void PutAnnotation<T>(IScope scope) where T : Attribute;

        void AddConverter(TypeConverterBinding typeConverterBinding);

        /// <summary>
        /// 获取匹配指定类型的转换器
        /// </summary>
        /// <param name="stringValue"></param>
        /// <param name="?"></param>
        /// <returns></returns>
        TypeConverterBinding GetConverter<T>(string stringValue, Errors errors, object source);

        /// <summary>
        /// 仅获取此层次的所有转换器
        /// </summary>
        /// <returns></returns>
        IEnumerable<TypeConverterBinding> GetConvertersThisLevel();

        /*if[AOP]*/
        void AddMethodAspect(MethodAspect methodAspect);

        IList<MethodAspect> MethodAspects
        {
            get;
        }
        /*end[AOP]*/

        void AddTypeListener(TypeListenerBinding typeListenerBinding);

        IList<TypeListenerBinding> TypeListenerBindings
        {
            get;
        }

        /// <summary>
        /// 禁止从一个binding到key的相应的注入器。子注入器将在他们的父注入器中将边界的key加入黑名单以阻止在父注入器
        /// 中即时绑定而避免冲突
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        void Blacklist<T>(Key<T> key);

        /// <summary>
        /// 如果在此注入器的边界上的key被禁止则返回true。这意味着此注入器的某个后代具有边界key
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        bool IsBlacklisted<T>(Key<T> key);

        /// <summary>
        /// 为所有注入器数据获取共享锁。这是一个当读取可变数据（例如即时绑定，绑定黑名单）时低粒度高竞争的锁
        /// </summary>
        /// <returns></returns>
        object Lock();

        /// <summary>
        /// 在此级别和父级别返回所有的scope绑定
        /// </summary>
        IDictionary<Type, IScope> Scopes
        {
            get;
        }
    }

        #region NONE State实现

        internal sealed class NoneState: IState
        {
            private NoneState() { }

            internal static NoneState INSTANCE = new NoneState();

            public IState  Parent
            {
	            get { throw new NotSupportedException(); }
            }

            public BindingImpl<T>  GetExplicitBinding<T>(Key<T> key)
            {
 	            return null;
            }

            public IDictionary<Key<T>,IBinding<T>>  GetExplicitBindingsThisLevel<T>()
            {
 	            throw new NotSupportedException();
            }

            public void  PutBinding<T>(Key<T> key, BindingImpl<T> binding)
            {
 	            throw new NotSupportedException();
            }

            public IScope  GetScope(Type scopingAnnotation)
            {
                return null;
            }

            public IScope  GetScope<T>() where T : Attribute
            {
                return null;
            }

            public void  PutAnnotation(Type annotationType, IScope scope)
            {
                throw new NotSupportedException();
            }

            public void  PutAnnotation<T>(IScope scope) where T : Attribute
            {
                throw new NotSupportedException();
            }

            public void  AddConverter(TypeConverterBinding typeConverterBinding)
            {
                throw new NotSupportedException();
            }

            public TypeConverterBinding  GetConverter<T>(string stringValue, Errors errors, object source)
            {
                throw new NotSupportedException();
            }

            public IEnumerable<TypeConverterBinding>  GetConvertersThisLevel()
            {
                return ImmutableSet<TypeConverterBinding>.Of();
            }

            public void  AddMethodAspect(MethodAspect methodAspect)
            {
                throw new NotSupportedException();
            }

            public ImmutableList<MethodAspect>  MethodAspects
            {
                get { return ImmutableList<MethodAspect>.EMPTY_IMMUTABLE_LIST; }
            }

            public void  AddTypeListener(TypeListenerBinding typeListenerBinding)
            {
                throw new NotSupportedException();
            }

            public IList<TypeListenerBinding>  TypeListenerBindings
            {
                get { return ImmutableList<TypeListenerBinding>.EMPTY_IMMUTABLE_LIST; }
            }

            public void  Blacklist<T>(Key<T> key)
            {
            }

            public bool  IsBlacklisted<T>(Key<T> key)
            {
                return true;
            }

            public object  Lock()
            {
                throw new NotSupportedException();
            }

            public IDictionary<Type,IScope>  Scopes
            {
                get { return new Dictionary<Type, IScope>(); }
            }


            public IBindingImpl GetExplicitBinding(Key key)
            {
                return null;
            }

            public IDictionary<Key, IBinding> GetExplicitBindingsThisLevel()
            {
                throw new NotSupportedException();
            }

            public void PutBinding(Key key, IBindingImpl binding)
            {
                throw new NotSupportedException();
            }

            IList<MethodAspect> IState.MethodAspects
            {
                get { return MethodAspects; }
            }
        }
        #endregion
}
